<?php

declare(strict_types=1);

namespace app\api\controller;

use app\admin\model\StoragePath;
use app\common\controller\ApiController;
use app\common\storage\ReaderStorage;
use app\common\storage\WriterStorage;
use think\facade\Validate;
use think\facade\View;
use think\Request;
use think\validate\ValidateRule;

class Node extends ApiController
{

    protected $modelPath = null;

    public function initialize()
    {
        parent::initialize();

        $path = $this->request->param('path', '/');

        $path = $this->initPath($path);

        $model_path = StoragePath::where("path", $path)->find();

        if (empty($model_path)) {
            return $this->returnMessage(['节点不存在']);
        }

        $this->modelPath = $model_path;
    }

    public function chlidren()
    {

        $order_field = $this->request->param('order_field', 'path');
        $order_sort = $this->request->param('order_sort', 'asc');

        $list_children = StoragePath::where("pid", $this->modelPath->id)->order($order_field, $order_sort)->select();

        return $this->returnMessage($list_children);
    }

    public function info()
    {
        return $this->returnMessage($this->modelPath);
    }

    public function create()
    {
        $validate = Validate::rule('name', ValidateRule::isRequire())
            ->rule('type', ValidateRule::isRequire()->in(['collection', 'node']));

        $post_data = $this->requestData($validate);

        $new_path = $this->initPath($this->modelPath->path . '/' . $post_data['name']);

        $model_new_path = StoragePath::where("path", $new_path)->find();

        if (!empty($model_new_path)) {
            return $this->returnMessage('创建失败，相同名称的节点已存在');
        }

        $model_new_path = new StoragePath();

        $model_new_path->path = $new_path;

        $model_new_path->type = $post_data['type'];

        $model_new_path->user_id = $this->modelUser->id;

        $model_new_path->save();

        return $this->returnMessage($model_new_path);
    }

    /**
     * 节点重命名
     * 
     * @param string $name
     *
     * @return void
     */
    public function rename()
    {

        // TODO:验证名称是否是合法的路径字符串

        $validate = Validate::rule('name', ValidateRule::isRequire());

        $post_data = $this->requestData($validate);

        $base_path = $this->modelPath->path;

        $path_arr = explode('/', $base_path);

        array_pop($path_arr);

        $path_arr[] = $post_data['name'];

        $new_path = implode('/', $path_arr);

        $model_check = StoragePath::where("path", $new_path)->find();

        if (!empty($model_check)) {
            return $this->returnMessage('修改失败，该名称已存在');
        }

        $this->modelPath->path = $new_path;
        $this->modelPath->save();

        return json_message();
    }

    public function write()
    {
        if ($this->modelPath->type != 'node') {
            return $this->returnMessage('上传失败，只有文件节点可以写入');
        }

        $file = $this->request->file('file');

        if (empty($file)) {
            return $this->returnMessage('上传失败，没有获取到文件数据');
        }

        $file_rescource = $file->openFile('rb');

        WriterStorage::write($this->modelPath, $file_rescource);

        

        return $this->returnMessage();
    }

    public function delete()
    {

        if ($this->modelPath->type == 'node') {
            WriterStorage::write($this->modelPath, '');
            $this->modelPath->delete();
        } else {
            StoragePath::where("path", 'like', "%" . $this->modelPath->path)->chunk(100, function ($list_path) {
                foreach ($list_path as  $model_path) {
                    WriterStorage::write($model_path, '');
                    $model_path->delete();
                }
            });

            $this->modelPath->delete();
        }

        return $this->returnMessage();
    }

    public function read()
    {
        $content = ReaderStorage::readAsString($this->modelPath);

        return download($content)->isContent(true)->mimeType($this->modelPath->content_type)->force(false);
    }

    public function copy()
    {
        $to_path = $this->request->param('to_path');

        
    }
}
